﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using SpectrumAnalyser.Common.Csv;
using SpectrumAnalyser.Common.Logs;
using SpectrumAnalyser.Data.Files.SpectrumDatabaseContracts.Repository;
using SpectrumAnalyser.ModelObjects;
using SpectrumAnalyser.ModelObjects.Enum;

namespace SpectrumAnalyser.Data.Files.SpectrumDatabase.Repository
{
    public class MaxSpectrumLinesRepository : ISpectrumLinesRepository
    {
        #region Implementation of ISpectrumPeaksRepository

        public IList<Peak> FillMatchedPeaks(IList<Peak> peaks, SpectrumDbConnection connection, LinesSearchSettings linesSearchSettings)
        {
            double wavelengthCoefficient = peaks.Any(x => x.Point2.X > 2000) ? 0.1 : 1;

            DataTable table = CsvReader.ReadTable(connection.ConnectionString, ' ');

            var numberFormatInfo = new NumberFormatInfo { NumberDecimalSeparator = "." };

            Logger.Log(DateTime.Now.ToString(CultureInfo.InvariantCulture));

            foreach (var peak in peaks)
            {
                IList<SpectrumPoint> localMax = new List<SpectrumPoint> { peak.Point2 }; //peak.Points.Where(x => x.Y == peak.Points.MaxBy(y => y.Y).Y).ToList();

                peak.MatchedChemicalElements = peak.MatchedChemicalElements ?? new List<ChemicalElement>();

                double waveLength;
                double intesity;
                string elementName;
                foreach (DataRow row in table.Rows)
                {
                    if (double.TryParse(row[0].ToString(), NumberStyles.Any, numberFormatInfo, out waveLength) && double.TryParse(row[2].ToString(), out intesity))
                    {
                        waveLength = waveLength/wavelengthCoefficient;
                        foreach (var spectrumPoint in localMax)
                        {
                            if (Math.Abs(spectrumPoint.X - waveLength) < linesSearchSettings.PeakWavelengthRange && Math.Abs(spectrumPoint.Y - intesity) < linesSearchSettings.PeakIntensityRange)
                            {
                                elementName = string.Format("{0} {1}", row[3], row[4]);
                                peak.MatchedChemicalElements.Add(new ChemicalElement
                                    {
                                        Name = elementName,
                                        OriginalIntensity = intesity
                                    });
                            }
                        }
                    }
                }
            }
            Logger.Log(DateTime.Now.ToString(CultureInfo.InvariantCulture));
            return peaks;
        }

        public WavelengthMeasure WavelengthMeasure
        {
            get { return WavelengthMeasure.Nanometers; }
        }

        public string ConnectionType
        {
            get { return ModelObjects.Enum.ConnectionType.Max.ToString(); }
        }

        #endregion
    }
}